#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>

//df98b715d5c6ed2b25817b6f255411a1df98b715d5c6ed2b25817b6f255411a1     //HEX密钥
unsigned char key[] = { //32字节
    0xdf, 0x98, 0xb7, 0x15, 0xd5, 0xc6, 0xed, 0x2b, 0x25, 0x81, 0x7b, 0x6f, 0x25, 0x54, 0x11, 0xa1,
    0xdf, 0x98, 0xb7, 0x15, 0xd5, 0xc6, 0xed, 0x2b, 0x25, 0x81, 0x7b, 0x6f, 0x25, 0x54, 0x11, 0xa1};
//2841ae97419c2973296a0d4bdfe19a4f     //HEX初始向量
unsigned char stdiv[] = {0x28, 0x41, 0xae, 0x97, 0x41, 0x9c, 0x29, 0x73, 0x29, 0x6a, 0x0d, 0x4b, 0xdf, 0xe1, 0x9a, 0x4f}; //16字节

void PKCS7_Pad(unsigned char *input, size_t input_len, unsigned char *output, size_t *output_len) {
    size_t padding = AES_BLOCK_SIZE - (input_len % AES_BLOCK_SIZE);
    *output_len = input_len + padding;
    memcpy(output, input, input_len);
    memset(output + input_len, (unsigned char)padding, padding);
}
void PKCS7_Unpad(unsigned char *input, size_t input_len, unsigned char *output, size_t *output_len) {
    unsigned char padding = input[input_len - 1];
    if (padding > AES_BLOCK_SIZE || padding == 0) {
        *output_len = 0;
        return;
    }
    *output_len = input_len - padding;
    memcpy(output, input, *output_len);
}

int main() {
    AES_KEY encryptkey;
    AES_KEY decryptkey;
    AES_set_encrypt_key(key, 256, &encryptkey);
    AES_set_decrypt_key(key, 256, &decryptkey);

    unsigned char plain_text[32]; // 对齐16字节
    size_t input_len = 30;
    memcpy(plain_text, "123456789012345678901234567890", input_len);
    printf("plain_text: "); for (int i = 0; i < 32; i++) { printf("%02X ", plain_text[i]); } printf("\n");

    unsigned char encrypted_text[32]; // 对齐16字节
    unsigned char tmpiv[16];
    memcpy(tmpiv, stdiv, 16);

    PKCS7_Pad(plain_text, input_len, plain_text, &input_len); // 使用PKCS7填充

    // AES_cbc_encrypt在加密的过程中会修改ivec(tmpiv)的内容，因此ivec参数不能是一个常量，而且不能在传递给加密函数后再立马传递给解密函数，必须重新赋值之后再传递给解密函数。
    // AES_cbc_encrypt可以对任意长度的输入数据进行加密，若输入数据不为16字节整数倍时，该函数内部会使用ZeroPadding自动对输入数据，进行填充，再进行加密。
    AES_cbc_encrypt(plain_text, encrypted_text, 32, &encryptkey, tmpiv, AES_ENCRYPT);

    printf("encrypted_: "); for (int i = 0; i < 32; i++) { printf("%02X ", encrypted_text[i]); } printf("\n");

    unsigned char decrypted_text[32]; // 对齐16字节
    memcpy(tmpiv, stdiv, 16);
    AES_cbc_encrypt(encrypted_text, decrypted_text, 32, &decryptkey, tmpiv, AES_DECRYPT);

    size_t output_len = 0;
    PKCS7_Unpad(decrypted_text, input_len, decrypted_text, &output_len); // 使用PKCS7解填充

    printf("decrypted_: "); for (int i = 0; i < output_len; i++) { printf("%02X ", decrypted_text[i]); } printf("\n");
    return 0;
}
